#include <TM1637Display.h>

// 数码管相关引脚
#define CLK 19
#define DIO 18
#define TEST_DELAY   2000

// 定义三个按钮的引脚
const int Button1 = 25;
const int Button2 = 26;
const int Button3 = 27;
// 蜂鸣器控制引脚，低电平触发
const int BuzzerPin = 4;
// 按键触发中断的标志位
volatile int button1_flag = 0;
volatile int button2_flag = 0;
volatile int button3_flag = 0;

// 双方比分
volatile int LEFT_COUNT = 0;
volatile int RIGHT_COUNT = 0;

// 右键按下
void Button1Click()
{
  button1_flag++;
}
// 中键按下
void Button2Click()
{
  button2_flag++;
}
// 左键按下
void Button3Click()
{
  button3_flag++;
}

//  嗒 一声长
void dah()
{
  digitalWrite(BuzzerPin,LOW);
  delay(400);
  digitalWrite(BuzzerPin,HIGH);
  delay(300);
}

//  滴 一声短
void dit()
{
  digitalWrite(BuzzerPin,LOW);
  delay(50);
  digitalWrite(BuzzerPin,HIGH);
  delay(300);
}

TM1637Display display(CLK, DIO);


uint8_t data[] = { 0xff, 0xff, 0xff, 0xff };

// 刷新屏幕
void refresh()
{
  // 输出左方分数的十位，如果为0则不显示
  if(LEFT_COUNT / 10 == 0)
    data[0] = 0x00;
  else
    data[0] = display.encodeDigit(LEFT_COUNT / 10);
  // 左方比分的个位
  data[1] = display.encodeDigit(LEFT_COUNT % 10);
  // 右方分数的十位，如果为0则不显示
  if(RIGHT_COUNT / 10 == 0)
    data[2] = 0x00;
  else
    data[2] = display.encodeDigit(RIGHT_COUNT / 10);
  // 右方比分的个位
  data[3] = display.encodeDigit(RIGHT_COUNT % 10);
  // 刷新双方得分
  display.setSegments(data);
}

void button1_pressed(){
      RIGHT_COUNT++;
      dit();
}
void button2_pressed()
{
      LEFT_COUNT = 0;
      RIGHT_COUNT = 0;
      // 响一声长
      dah();
}
void button3_pressed(){
      LEFT_COUNT++;
      dit();
}

//接收端使用16号引脚
void setup() {
  Serial.begin(115200);
  // 使用串口2作为输入时，17号TX2引脚也不能作为普通GPIO使用
  Serial2.begin(1583);
  // 初始化蜂鸣器
  pinMode(BuzzerPin, OUTPUT);
  // 蜂鸣器控制引脚默认输出高电平
  digitalWrite(BuzzerPin, HIGH);
  
  // 初始化按键为上拉输入模式
  pinMode(Button1, INPUT_PULLUP);
  pinMode(Button2, INPUT_PULLUP);
  pinMode(Button3, INPUT_PULLUP);
  
  // 将函数附加到外部中断
  attachInterrupt(Button1,Button1Click,FALLING);
  attachInterrupt(Button2,Button2Click,FALLING);
  attachInterrupt(Button3,Button3Click,FALLING);
  
  display.setBrightness(0x0f);
  delay(TEST_DELAY);
}

void loop() {
  unsigned char instruction;
  if(Serial2.available()){
    instruction = Serial2.read();
    Serial.write(instruction);
    switch(instruction){
      case '1':
        button1_pressed();
        break;
      case '2':
        button2_pressed();
        break;
      case '3':
        button3_pressed();
        break;
      default: 
        break;
    }
  }
  if(button1_flag){
    delay(10);
    // 消抖
    // 左键按下 左方加分
    if(!digitalRead(Button1)){
      button1_pressed();
    }
    button1_flag = 0;
  }
  if(button2_flag){
    delay(10);
    // 中键按下，双方分数归零
    if(!digitalRead(Button2)){
      button2_pressed();
    }
    button2_flag = 0;
  }
  if(button3_flag){
    delay(10);
    // 右键按下，右方加分
    if(!digitalRead(Button3)){
      button3_pressed();
    }
    button3_flag = 0;
  }
  refresh();
}
